const { getWeixinPlatform } = require('./weixin');
const createConfig = require('uni-config-center');

const requiredConfig = {
    'web.weixin-h5': ['appid', 'appsecret'],
    'web.weixin-web': ['appid', 'appsecret'],
    'app.weixin': ['appid', 'appsecret'],
    'mp-weixin.weixin': ['appid', 'appsecret'],
    'app.qq': ['appid', 'appsecret'],
    'mp-alipay.alipay': ['appid', 'privateKey'],
    'app.apple': ['bundleId'],
};

const uniIdConfig = createConfig({
    pluginId: 'uni-id',
});

class ConfigUtils {
    constructor({ context } = {}) {
        this.context = context;
        this.clientInfo = context.getClientInfo();
        const { appId, uniPlatform } = this.clientInfo;
        this.appId = appId;
        switch (uniPlatform) {
            case 'app':
            case 'app-plus':
                this.platform = 'app';
                break;
            case 'web':
            case 'h5':
                this.platform = 'web';
                break;
            default:
                this.platform = uniPlatform;
                break;
        }
    }

    getConfigArray() {
        let configContent;
        try {
            configContent = require('uni-config-center/uni-id/config.json');
        } catch (error) {
            throw new Error('Invalid config file\n' + error.message);
        }
        if (configContent[0]) {
            return Object.values(configContent);
        }
        configContent.isDefaultConfig = true;
        return [configContent];
    }

    getAppConfig() {
        const configArray = this.getConfigArray();
        return (
            configArray.find((item) => item.dcloudAppid === this.appId) ||
            configArray.find((item) => item.isDefaultConfig)
        );
    }

    getPlatformConfig() {
        const appConfig = this.getAppConfig();
        if (!appConfig) {
            throw new Error(
                `Config for current app (${this.appId}) was not found, please check your config file or client appId`
            );
        }
        const platform = this.platform;
        if ((this.platform === 'app' && appConfig['app-plus']) || (this.platform === 'web' && appConfig.h5)) {
            throw new Error(
                `Client platform is ${this.platform}, but ${
                    this.platform === 'web' ? 'h5' : 'app-plus'
                } was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary?id=m-to-co`
            );
        }

        const defaultConfig = {
            tokenExpiresIn: 7200,
            tokenExpiresThreshold: 1200,
            passwordErrorLimit: 6,
            passwordErrorRetryTime: 3600,
        };
        return Object.assign(defaultConfig, appConfig, appConfig[platform]);
    }

    getOauthProvider({ provider } = {}) {
        const clientPlatform = this.platform;
        let oatuhProivder = provider;
        if (provider === 'weixin' && clientPlatform === 'web') {
            const weixinPlatform = getWeixinPlatform.call(this.context);
            if (weixinPlatform === 'h5' || weixinPlatform === 'web') {
                oatuhProivder = 'weixin-' + weixinPlatform; // weixin-h5 公众号，weixin-web pc端
            }
        }
        return oatuhProivder;
    }

    getOauthConfig({ provider } = {}) {
        const config = this.getPlatformConfig();
        const clientPlatform = this.platform;
        const oatuhProivder = this.getOauthProvider({
            provider,
        });
        const requireConfigKey = requiredConfig[`${clientPlatform}.${oatuhProivder}`] || [];
        if (!config.oauth || !config.oauth[oatuhProivder]) {
            throw new Error(`Config param required: ${clientPlatform}.oauth.${oatuhProivder}`);
        }
        const oauthConfig = config.oauth[oatuhProivder];
        requireConfigKey.forEach((item) => {
            if (!oauthConfig[item]) {
                throw new Error(`Config param required: ${clientPlatform}.oauth.${oatuhProivder}.${item}`);
            }
        });
        return oauthConfig;
    }

    getHooks() {
        if (uniIdConfig.hasFile('hooks/index.js')) {
            return require(uniIdConfig.resolve('hooks/index.js'));
        }
        return {};
    }
}

module.exports = ConfigUtils;
